module Explode.GameConfig;
private import System.BootInfo;
private import System.Console;
private import std.string;
private import std.file;
private import std.format;
private import Sound.Manager;

public static final class GameConfig {
	public static const int SYSVER = 20080218;
	public static const int SCORE_GOLD		 =  200;
	public static const int SCORE_STAGECLEAR = 1000;
	public static const int SCORE_NOKILL	 = 5000;
	public static const int SCORE_NODIG		 = 5000;
	
	public static string playerName = "RUNNER";
	public static string mapTexture		= "_data/img/mapchip.bmp";
	public static string playerTexture  = "_data/img/men.bmp";
	public static string enemyTexture   = "_data/img/enemy.bmp";
	public static string stageDir		= "_data/stage";

	public static string missSound		= "_data/sound/dead.ogg";
	public static string digSound		= "_data/sound/dig.ogg";
	public static string goalSound		= "_data/sound/clear.ogg";
	public static string ladderSound	= "_data/sound/ladder.ogg";
	public static string goldSound		= "_data/sound/gold.ogg";

	public static string titleBgm		= "_data/sound/bgm_title.ogg";
	public static string startBgm		= "_data/sound/bgm_start.ogg";
	public static string gameBgm		= "_data/sound/bgm_game.ogg";

	private static int[]  _button=[0,1,2,3,4,5,6,7,8,9];
	private static string _cpu = "NORMAL";
	private static int _lastStage = 0;
	private static int _bestStage = 0;
	private static int _hiscore	  = 0;
	private static int _soundVolume   = 100 , _bgmVolume = 100;
	
	private static int _stageLength = 1;
	private static int _editStageLength = 1;
	private static int _autoDemo = 0;

	public static int  getButtonMap( int num ){ 
		if ( num < 0 || num >= _button.length )return 0;
		return _button[num];
	} //
	// 逆引き
	public static int  getButtonMapR( int num ){ 
		foreach( int i , int j ; _button ) {
			if ( num == j ) return i;
		}
		return -1;
	} //

	public static void setButtonMap( int num , int map ){
		if ( num < 0 || num >= _button.length )return;
		_button[num] = map;
		update();
	} //
	
	public static string cpu(){return _cpu;} //
	
	public static int lastStage(){
		return _lastStage;
	} //
	public static void lastStage( int num){
		_lastStage = num;
		update();
	} //

	public static int bestStage(){
		return _bestStage;
	} //
	public static void bestStage( int num ){
		if ( _bestStage >= num ) return;
//		Console.writeln("***bestStage update %d ->%d" , _bestStage , num );
		_bestStage = num;
		
		update();
	} //

	public static int soundVolume() {
		return _soundVolume;
	} //
	public static void soundVolume( int v ) {
		if ( v < 0 ) v = 0;
		if ( v > 100 ) v = 100;
		_soundVolume = v;
		update();
	} //
	public static int bgmVolume(){
		return _bgmVolume;
	} //
	public static void bgmVolume( int v ) {
		if ( v < 0 ) v = 0;
		if ( v > 100 ) v = 100;
		_bgmVolume = v;
		update();
	} //

	public static int stageLength() {
		return _stageLength;
	} //

	public static int editStageLength() {
		return _editStageLength;
	} //

	public static int hiscore(){
		return _hiscore;
	} //
	public static void hiscore( int num){
		if ( _hiscore >= num ) return;
		_hiscore = num;
		update();
	} //

	public static bool autoDemo() {
		return _autoDemo == 1 ;
	} //

	public static void cpu( string mode){
		switch( mode ){
			case "NORMAL":
			case "FC":
			case "GBA":
			case "PC":
			case "BBR":
				_cpu = mode;
				update();
				break;
			default:
				_cpu = "NORMAL";
				update();
				break;
		} //
	} //

	public static void init() {
		alias SystemConfig s;
		alias s.getParam sg;
		foreach ( int i ; _button ) {
			_button[i] = sg( "BUTTON"~ std.string.toString(i) , i );
		}
		_cpu	   = sg( "CPU" , "NORMAL" );
		_lastStage = sg( "LASTSTAGE" , 1  );
		_bestStage = sg( "BESTSTAGE" , 1  );
		_hiscore   = sg( "HISCORE"   , 0  );
		_soundVolume    = s.getParam( "SOUNDVOLUME"  , 100 );
		_bgmVolume    = s.getParam( "BGMVOLUME"    , 100 );
		
		int i = 1;
		while ( true ) {
			string fileName = format( "%s/stage%04d.txt" , stageDir , i );
			if ( !exists( fileName ) ) break; 
			i++;
		}
		_stageLength = i -1;
		i = 1;
		while ( true ) {
			string fileName = format( "%s/edit%04d.txt" , stageDir , i );
			if ( !exists( fileName ) ) break; 
			i++;
		}
		_editStageLength = i -1;
		
		_autoDemo = sg( "SCREENSAVER" , 0 );
		
		SoundManager.bgmVolume   = _bgmVolume;
		SoundManager.soundVolume = _soundVolume;
		update();
	} //
	
	public static void update(){
		foreach ( int i , int j ; _button ) {
			SystemConfig.setParam( "BUTTON"~ std.string.toString(i) , j );
		}
		SystemConfig.setParam("CPU",_cpu);
		SystemConfig.setParam("LASTSTAGE" , _lastStage );
		SystemConfig.setParam("BESTSTAGE" , _bestStage );
		SystemConfig.setParam("HISCORE"   , _hiscore   );
		SystemConfig.setParam( "SOUNDVOLUME"  , _soundVolume  );
		SystemConfig.setParam( "BGMVOLUME"    , _bgmVolume );
	} //
	
} //


public class GameParam{
	private int _stageNum  = 1;
	private int _bestStage = 0;
	private int _score	   = 0;
	private int _hiscore  = 0;

	public int lastStage = 1;
	public int life		 = 5;
	public int frameCnt  = 0;
	public int bestTime = -1;

	public int score(){
		return _score;
	} //
	public void score( int n ) {
		alias GameConfig g;
		_score = n;
		if ( _hiscore < n ) {
			_hiscore  = n;
			g.hiscore = n;
		}
	} //

	public int hiscore(){
		return _hiscore;
	} //
	public void hiscore( int n ) {
		alias GameConfig g;
		if ( _hiscore < n ) {
			_hiscore  = n;
			g.hiscore = n;
		}
	} //

	public int stageNum() {
		return _stageNum;
	} //
	public void stageNum( int n ) {
		alias GameConfig g;
		_stageNum = n;
		lastStage = n;
		g.lastStage = n;
		if ( _bestStage < n ) {
			g.bestStage = n;
		}
	} //
	public int bestStage() { 
		return _bestStage;
	} //

	public bool isGameover() {
		return ( life == 0 );
	} //

	public void reset(){
		alias GameConfig g;
		stageNum  = 1;
		life	  = 5;
		score	  = 0;
		frameCnt  = 0;
		_bestStage = g.bestStage;
	} //
	
	public void resetStageParam(){
		bestTime = 0;
	} //
} //
